package com.casa_apoio.estoque.controller;

import com.casa_apoio.estoque.mode.dao.EntradaDAO;
import com.casa_apoio.estoque.mode.dao.EstoqueDAO;
import com.casa_apoio.estoque.mode.dao.FornecedorDAO;
import com.casa_apoio.estoque.mode.dao.ProdutoDAO;
import com.casa_apoio.estoque.mode.entity.CabEstoque;
import com.casa_apoio.estoque.mode.entity.Entrada;
import com.casa_apoio.estoque.mode.entity.Fornecedor;
import com.casa_apoio.estoque.mode.entity.Produto;
import com.casa_apoio.model.dao.AcessoDAO;
import com.casa_apoio.model.dao.FuncionarioDAO;
import com.casa_apoio.model.entity.Acesso;
import com.casa_apoio.model.entity.Funcionario;
import com.casa_apoio.util.FacesContextUtil;
import java.io.Serializable;
import java.text.NumberFormat;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

@ManagedBean
@ViewScoped
public class MbEntrada implements Serializable {

    private CabEstoque cabEstoque;
    private List<CabEstoque> cabEstoques;
    private Fornecedor fornecedor;
    private Integer idFornecedor;
    private Entrada entrada;
    private List<Entrada> entradas;
    private boolean edit;
    private Produto produto;
    private List<Produto> produtos;
    private Funcionario funcionario;
    private double totalNF;

    private EntradaDAO entradaDAO() {
        EntradaDAO<CabEstoque> dao = new EntradaDAO<CabEstoque>(CabEstoque.class, FacesContextUtil.getRequestSession());
        return dao;
    }

    private AcessoDAO acessoDAO() {
        AcessoDAO<Acesso> dao = new AcessoDAO<Acesso>(Acesso.class, FacesContextUtil.getRequestSession());
        return dao;
    }

    private EstoqueDAO estoqueDAO() {
        EstoqueDAO<Entrada> dao = new EstoqueDAO<Entrada>(Entrada.class, FacesContextUtil.getRequestSession());
        return dao;
    }

    private FuncionarioDAO funcionarioDAO() {
        FuncionarioDAO<Funcionario> dao = new FuncionarioDAO<Funcionario>(Funcionario.class, FacesContextUtil.getRequestSession());
        return dao;
    }

    private ProdutoDAO produtoDAO() {
        ProdutoDAO<Produto> dao = new ProdutoDAO<Produto>(Produto.class, FacesContextUtil.getRequestSession());
        return dao;
    }

    private FornecedorDAO fornecedorDAO() {
        FornecedorDAO<Fornecedor> dao = new FornecedorDAO<Fornecedor>(Fornecedor.class, FacesContextUtil.getRequestSession());
        return dao;
    }

    public void adicionarProduto(ActionEvent ev) {
        System.out.println("Produto " + entrada.getProduto().getIdProduto() + " Validade " + entrada.getValidade() + " Qtde " + entrada.getQuantidade() + " Vlr Uni" + entrada.getValor() + " Total " + (entrada.getValor() * entrada.getQuantidade()));
        entrada.setCabEstoque(cabEstoque);
        estoqueDAO().salvar(entrada);
        caregarProdutoNota(cabEstoque.getIdCabEstoque());
        entrada = new Entrada();
    }

    public void atualizarLista(ActionEvent ev) {
        caregarProdutoNota(cabEstoque.getIdCabEstoque());
    }

    public void atualizarCabecalho(ActionEvent ev) {
        cabEstoques = entradaDAO().entradasNaoFinalizada();
    }

    private void caregarProdutoNota(Integer cabecalho) {
        entradas = estoqueDAO().entradaEstoqueNaoFinalizada(cabecalho);
        totalNF = 0;
        for (Entrada e : entradas) {
            totalNF += e.getValor() * e.getQuantidade();
        }

        System.out.println(">>>>>>>>  Total " + totalNF);
    }

    public String finalizarEntrada() {
        NumberFormat nf = NumberFormat.getCurrencyInstance();
        System.out.println(" 1 " + nf.format(cabEstoque.getVlrTotal()) + " 2 " + nf.format(this.getTotalNF()));
        if (cabEstoque.getVlrTotal() == this.getTotalNF()) {
            try {
                for (Entrada e : entradas) {
                    e.setFinalizado(true);
                    estoqueDAO().atualizar(e);

                    produto = (Produto) produtoDAO().getEntity(e.getProduto().getIdProduto());
                    produto.setEstoque(produto.getEstoque() + e.getQuantidade());
                    produtoDAO().atualizar(produto);
                }
                cabEstoque.setFinalizado(true);
                entradaDAO().atualizar(cabEstoque);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Finalizado com sucesso", "Informação"));
            } catch (Exception e) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Falha na finalização da entrada", "Informação"));
                return null;
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Valor total da nota não confere", "Informação"));
            return null;
        }
        return "/restrict/estoque/entrada.faces";
    }

    public String excluirProduto(Entrada estoque) {
        estoqueDAO().excluir(estoque);
        caregarProdutoNota(cabEstoque.getIdCabEstoque());
        return null;
    }

    public String lancarProdutos(Integer cabecalho) {
        cabEstoque = (CabEstoque) entradaDAO().getEntity(cabecalho);
        caregarProdutoNota(cabEstoque.getIdCabEstoque());
        setEdit(true);
        return null;
    }

    public void confirmaFornecedor() {
        this.cabEstoque = new CabEstoque();
        try {
            this.cabEstoque.setFornecedor((Fornecedor) fornecedorDAO().getEntity(idFornecedor));
            System.out.println(fornecedorDAO().getEntity(idFornecedor).toString());
        } catch (Exception e) {
            System.out.println("=== ===  Erro" + e.getMessage());
        }
    }

    public void salvarCabecalho(ActionEvent ev) {
        //this.cabEstoque.setFornecedor((Fornecedor) fornecedorDAO().getEntity(idFornecedor));
        if (cabEstoque.getIdCabEstoque() == null || cabEstoque.getIdCabEstoque() < 1) {
            cabEstoque.setFuncionario(usuarioLogado());
            entradaDAO().salvar(cabEstoque);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Cabeçalho Salvo com Sucesso", ""));
        }
        setEdit(true);
        //atualizarTela();     
    }

    public void habilitarEdicaiCabecalho(ActionEvent ev) {
        setEdit(false);
    }

    public void novoCabecalho(ActionEvent ev) {
        setEdit(false);
        cabEstoque = new CabEstoque();
        atualizarTela();
    }

    public String atualizarTela() {
        return "/restrict/estoque/entrada.faces";
    }

    private Funcionario usuarioLogado() {
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext external = context.getExternalContext();
        String login = external.getRemoteUser();

        List<Acesso> lista = acessoDAO().verificaLogin(login);
        Acesso a = lista.get(0);
        Funcionario f = (Funcionario) funcionarioDAO().getEntity(a.getFuncionario().getIdFuncionario());
        return f;
    }

    public CabEstoque getCabEstoque() {
        if (cabEstoque == null) {
            cabEstoque = new CabEstoque();
        }
        return cabEstoque;
    }

    public void setCabEstoque(CabEstoque cabEstoque) {
        this.cabEstoque = cabEstoque;
    }

    public List<CabEstoque> getCabEstoques() {
        if (cabEstoques == null) {
            cabEstoques = entradaDAO().entradasNaoFinalizada();
        }
        return cabEstoques;
    }

    public void setCabEstoques(List<CabEstoque> cabEstoques) {
        this.cabEstoques = cabEstoques;
    }

    public Fornecedor getFornecedor() {
        if (fornecedor == null) {
            fornecedor = new Fornecedor();
        }
        return fornecedor;
    }

    public void setFornecedor(Fornecedor fornecedor) {
        this.fornecedor = fornecedor;
    }

    public Integer getIdFornecedor() {
        return idFornecedor;
    }

    public void setIdFornecedor(Integer idFornecedor) {
        this.idFornecedor = idFornecedor;
    }

    public Entrada getEntrada() {
        if (entrada == null) {
            entrada = new Entrada();
        }
        return entrada;
    }

    public void setEntrada(Entrada estoque) {
        this.entrada = estoque;
    }

    public boolean isEdit() {
        return edit;
    }

    public void setEdit(boolean edit) {
        this.edit = edit;
    }

    public Produto getProduto() {
        if (produto == null) {
            produto = new Produto();
        }
        return produto;
    }

    public void setProduto(Produto produto) {
        this.produto = produto;
    }

    public List<Produto> getProdutos() {
        if (produtos == null) {
            produtos = produtoDAO().listaProdutos();
        }
        return produtos;
    }

    public void setProdutos(List<Produto> produtos) {
        this.produtos = produtos;
    }

    public Funcionario getFuncionario() {
        return funcionario;
    }

    public void setFuncionario(Funcionario funcionario) {
        this.funcionario = funcionario;
    }

    public List<Entrada> getEntradas() {
        return entradas;
    }

    public void setEntradas(List<Entrada> entradas) {
        this.entradas = entradas;
    }

    public double getTotalNF() {
        return totalNF;
    }

    public void setTotalNF(double totalNF) {
        this.totalNF = totalNF;
    }

}
